package fi.aalto.cse.T110_5150.P2PClient;

import java.util.ArrayList;
import java.util.Iterator;

public abstract class NumberArray<T extends Number> extends ArrayList<T> {

	private static final long serialVersionUID = 4682997642038477634L;
	
	public void decode(String s) throws P2PFormatException {
		s = s.trim();

		if (s.startsWith("{") && s.endsWith("}")) {
			String[] terms = s.substring(1, s.length() - 1).split(",");
			
			try {
				for (int i = 0; i < terms.length; ++i) {
					add(decodeSingleNumber(terms[i].trim()));
				}

				return;

			} catch (NumberFormatException e) {
			}

		}

		throw new P2PFormatException(String.format("Invalid integer array string '%s'", s));
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public boolean equals(Object o) {
		return (o instanceof NumberArray) && equals((NumberArray<T>)o);
	}
	
	public boolean equals(NumberArray<T> array) {
		
		if (array != null & array.size() == size()) {
			
			for (Iterator<T> it1 = iterator(), it2 = array.iterator(); it1.hasNext();) {
				
				if (!it1.next().equals(it2.next())) {				
					return false;					
				}
			}
			
			return true;
			
		}
		
		return false;
	}
	
	public String toString() {		
		return toString(numberFormat());		
	}	
	
	public String toString(String format) {	
		
		if (!isEmpty()) {
			StringBuffer buffer = new StringBuffer();
			
			for (Iterator<T> it = iterator(); it.hasNext(); ) {
				buffer.append(' ');
				buffer.append(String.format(format, it.next()));
				buffer.append(',');
			}
			
			return String.format("{%s}", buffer.substring(0, buffer.length() -1).trim());			
		} else {
			return "{}";			
		}		
	}	
	
	protected abstract String numberFormat();
	
	protected abstract T decodeSingleNumber(String s);
}
